//
//  SearchSourceListElement.m
//  SolarSeek
//
//  Created by Erick Fejta on 05/03/17.
//  Copyright 2005 Erick Fejta. All rights reserved.
//

#import "SearchSourceListElement.h"
#import "SearchView.h"
#import "Searches.h"
#import "Shares.h"
#import "SearchesController.h"
#import "ApplicationDefaults.h"


typedef enum { otResults=1,otPeers } ObservingTypes;

@implementation SearchSourceListElement
- (id)initWithSearch:(Search *)search autosaves:(BOOL)autosave{
	NSAssert(search,@"Search cannot be nil.");
	if(self = [super initWithView:[NSApp viewSearchResults]]) {
		_autosave = autosave;
		_search = [search retain];
		[_search addObserver:self forKeyPath:@"results" options:nil context:(void *)otResults];
		[_search addObserver:self forKeyPath:@"peers" options:nil context:(void *)otPeers];
		_rectVisible = NSMakeRect(0,0,0,0);
		_sharesSelected = nil;
	}
	return self;
}

- (void)dealloc {
	[_search removeObserver:self forKeyPath:@"peers"];
	[_search removeObserver:self forKeyPath:@"results"];
	[_search release];
	[super dealloc];
}

#pragma mark KVO

- (BOOL)autosaves { return _autosave; }
- (Search *)search { return _search; }
- (NSArray *)searches { return [NSArray arrayWithObject:_search]; }
- (NSArray *)shares { return [_search results]; }
- (NSImage *)icon { return [NSImage imageNamed:@"sourcelistSearch"]; }
- (NSString *)titleWindow { return [@"Search for " stringByAppendingString:[_search query]]; }
- (NSString *)name { 
	NSString *first = [_search query];
	NSString *second = @"";
	unsigned count = [[_search results] count];
	if(count && [[NSUserDefaults standardUserDefaults] boolForKey:SolarSeekDefaultShowNumberOfFilesFoundForCurrentSearch]) {
		unsigned countPeers = [[_search peers] count];
		if(count / countPeers < 3 || count / countPeers > 50)
			second = [NSString stringWithFormat:@" (%d/%d)",count,countPeers];
		else second = [NSString stringWithFormat:@" (%d)",count];
	}
	[NSString stringWithFormat:@"%@%@",first,second]; 
}
- (NSArray *)participants { return [_search peers] ; }

- (void)setAutosaves:(BOOL)autosave { _autosave = autosave; }

- (void)removeFromSourceList { 
	[[[NSApp engine] searchesController] endSearch:[self search]];
}

- (void)scheduleSaveAutomatically {
	[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(saveAutomatically) object:nil];
	[self performSelector:@selector(saveAutomatically) withObject:nil afterDelay:10.0];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
/*
	NSArray *a = [[NSArray alloc] initWithObjects:keyPath,object,change,[NSNumber numberWithLong:(long)context],nil];
	[self performSelectorOnMainThread:@selector(observe:) withObject:a waitUntilDone:YES];
	[a release];
}

- (void)observe:(NSArray *)observeArray {
	NSString *keyPath = [observeArray objectAtIndex:0];
	id object = [observeArray objectAtIndex:1];
	NSDictionary *change = [observeArray objectAtIndex:2];
	void *context = (void *)[[observeArray objectAtIndex:3] longValue];
*/	
	NSAssert1(object==_search,@"Observed wrong object (%@).",object);
	switch((int)context) {
		case otResults: {
			int kind = [[change objectForKey:NSKeyValueChangeKindKey] intValue];
			if(kind == NSKeyValueChangeSetting) {
				[self willChangeValueForKey:@"shares"];
				[self didChangeValueForKey:@"shares"];
			}
			else {
				[self willChange:[[change objectForKey:NSKeyValueChangeKindKey] intValue] valuesAtIndexes:[change objectForKey:NSKeyValueChangeIndexesKey] forKey:@"shares"];
				[self didChange:[[change objectForKey:NSKeyValueChangeKindKey] intValue] valuesAtIndexes:[change objectForKey:NSKeyValueChangeIndexesKey] forKey:@"shares"];
			}
			if([self autosaves]) {
				[self performSelectorOnMainThread:@selector(scheduleSaveAutomatically) withObject:nil waitUntilDone:YES];
			}
			break;
		}
		case otPeers: {
			[self willChange:[[change objectForKey:NSKeyValueChangeKindKey] intValue] valuesAtIndexes:[change objectForKey:NSKeyValueChangeIndexesKey] forKey:@"participants"];
			[self didChange:[[change objectForKey:NSKeyValueChangeKindKey] intValue] valuesAtIndexes:[change objectForKey:NSKeyValueChangeIndexesKey] forKey:@"participants"];
			break;
		}
		default: 
			[NSException raise:@"InvalidKeyPathException" format:@"Cannot observe %@.",keyPath];
	}
	[self refreshAndRequestAttention:YES];
}

- (void)setSelected:(BOOL)selected {
	if(selected == NO) {
		_rectVisible = [(SearchView *)[self view] contentView];
		NSArray *a = [[(SearchView *)[self view] sharesSelected] retain];
		[_sharesSelected release];
		_sharesSelected = a;
		
	}
	else {
		[(SearchView *)[self view] setContentView:_rectVisible];
		if(_sharesSelected)
			[(SearchView *)[self view] setSharesSelected:_sharesSelected];
	}
	[super setSelected:selected];
}


- (void)saveToFile:(NSString *)file { 
	NSAssert(file,@"Must include a filename.");
	NSString *dir = [file stringByDeletingLastPathComponent];
	if([[NSFileManager defaultManager] fileExistsAtPath:dir] == YES || [[NSFileManager defaultManager] createDirectoryAtPath:dir attributes:nil]==YES) {
		//fejta: TODO: medium: report whether the save is successful!
		[[[NSApp engine] searchesController] saveSearch:_search toFile:file];
	}
	else
			[NSException raise:@"DirectoryCreationException" format:@"Could not create the directory: %@.  Aborting save.",dir];
}


- (void)saveAutomatically {
	[NSThread detachNewThreadSelector:@selector(saveAutomaticallyInBackground) toTarget:self withObject:nil];
}

- (void)saveAutomaticallyInBackground {
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	NS_DURING
		[self saveToFile:[[NSString stringWithFormat:@"~/Library/Application Support/SolarSeek/%@.search.plist",[_search query]] stringByExpandingTildeInPath]];
	NS_HANDLER
		NSLog(@"%@",localException);
		NSLog(@"Save aborted.  Continuing...");
	NS_ENDHANDLER
	[pool release];
}

- (void)savePanelDidEnd:(NSSavePanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo {
	if(returnCode==NSOKButton) {
		[self saveToFile:[sheet filename]];
	}
}

- (void)save {
	NSSavePanel *sp = [NSSavePanel savePanel];
	[sp setRequiredFileType:@"search.plist"];
	[sp setCanCreateDirectories:YES];
	[sp beginSheetForDirectory:nil file:nil modalForWindow:[NSApp keyWindow] modalDelegate:self didEndSelector:@selector(savePanelDidEnd:returnCode:contextInfo:) contextInfo:nil];
}
	
@end
